---------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------
-- File: device_ram.vhd - Device memory source file. 
--
-- Author: Andy Schneck
--
-- Description: This file represents the memory block for each device. It is used to
--              store data from the I/O devices connected to the FPGA. Since each I2C
--              module can contain 8 devices on one bus, there will be a separate 
--              memory block for each module of size 8.
--
-- Inputs: clock - System clock
--         data_in - Input data from the I/O devices.
--         address - Address to write to or read from in memory
--         write_enable - Determines if the command is a write
--
-- Outputs: data_out - The outgoing payload data for a write command.
---------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

----------------------------------------------
-- entity declaration for the device memory -- 
----------------------------------------------
entity device_ram is
	generic(
		    address_width : integer := 4; -- Size of the memory component
		    data_width	  : integer := 32 -- Size of the data
		    ); 
	port(
		 clock        : in std_logic; -- System clock
		 data_in      : in std_logic_vector(data_width - 1 downto 0); -- Incoming data
		 address      : in  std_logic_vector(address_width - 1 downto 0); -- Address to access	
		 write_enable : in  std_logic; -- Specifies a write to memory command (active high)
		 data_out     : out std_logic_vector(data_width - 1 downto 0) -- Outgoing data
		 ); 
end device_ram;

---------------------------------------------
-- Architecture body for the device memory -- 
---------------------------------------------
architecture behav of device_ram is
	type ram is array(0 to 2 * address_width - 1) of std_logic_vector(data_width - 1 downto 0);
	signal ram_block : ram;
begin
	process(clock)
	begin
		if(rising_edge(clock)) then
			if(write_enable = '1') then	-- If write enable is high, write to the specified address	
			    ram_block(conv_integer(address)) <= data_in; 
			else -- if the command is a read
				data_out <= ram_block(conv_integer(address));
			end if;
		end if;
	end process;
end behav;
